package org.fixies.spreadsheet.excel.poi;

import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.fixies.resource.ResourceLoader;
import org.fixies.spreadsheet.interpreter.BookContext;
import org.fixies.spreadsheet.interpreter.SheetContext;
import org.fixies.utils.IOUtils;
import org.fixies.utils.UnexpectedProblemException;

import java.io.IOException;
import java.io.InputStream;


/**
 * HSSF用ブックコンテキスト
 *
 * @author Kawasaki
 */
public class HSSFBookContext implements BookContext {

    /**
     * HSSFワークブック
     */
    private HSSFWorkbook book_;

    /**
     * シートのインデックス
     */
    private int sheetIndex_ = -1;

    /**
     * 現在のシートコンテキスト
     */
    private SheetContext current_;

    /**
     * コンストラクタ
     *
     * @param is Bookを読み込むInputStream
     */
    public HSSFBookContext(InputStream is) {
        load(is);
    }

    /**
     * コンストラクタ
     *
     * @param book HSSFワークブック
     */
    public HSSFBookContext(HSSFWorkbook book) {
        book_ = book;
    }

    /**
     * デフォルトコンストラクタ
     */
    public HSSFBookContext() {
    }

    /**
     * @see org.fixies.spreadsheet.excel.poi.poi.BookContext#next()
     */
    public SheetContext next() {
        sheetIndex_++;
        current_ =
                createSheetContext(book_.getSheetAt(sheetIndex_), book_
                        .getSheetName(sheetIndex_));
        return current_;
    }

    /**
     * @see org.fixies.spreadsheet.interpreter.BookContext#current()
     */
    public SheetContext current() {
        if (current_ == null) {
            return next();
        }
        return current_;
    }


    /**
     * @see org.fixies.spreadsheet.excel.poi.poi.BookContext#hasNext()
     */
    public boolean hasNext() {
        return sheetIndex_ < (book_.getNumberOfSheets() - 1);
    }


    /**
     * @see org.fixies.spreadsheet.interpreter.BookContext#load(java.io.InputStream)
     */
    private void load(InputStream is) {
        if (is == null) {
            throw new IllegalArgumentException("argument must not be null");
        }
        try {
            POIFSFileSystem fs = new POIFSFileSystem(is);
            book_ = new HSSFWorkbook(fs);
        } catch (IOException e) {
            throw new UnexpectedProblemException(e);
        }
    }

    protected SheetContext createSheetContext(HSSFSheet sheet, String sheetName) {
        return new HSSFSheetContext(sheet, sheetName);
    }

    @Override
    public void load(String resourceName, ResourceLoader resourceLoader) {
        InputStream in = resourceLoader.loadResource(resourceName + ".xls");
        try {
            load(in);
        } finally {
            IOUtils.closeQuietly(in);
        }

    }
}
